package com.zombie.logic.core.box2d;

import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.Manifold;
import com.zombie.logic.Formulas;
import com.zombie.logic.object.Bullet;
import com.zombie.logic.object.GameObject;
import com.zombie.logic.object.LiveObject;
import com.zombie.logic.object.StaticObject;


public class ContactListener implements com.badlogic.gdx.physics.box2d.ContactListener {

	@Override
	public void beginContact(Contact contact) {
		Body b1,b2;
		b1 = contact.getFixtureA().getBody();
		b2 = contact.getFixtureB().getBody();
		GameObject o1, o2;
		o1 = (GameObject) contact.getFixtureA().getBody().getUserData();
		o2 = (GameObject) contact.getFixtureB().getBody().getUserData();

		// only static object have null user data
		if (o1 == null && o2 == null)
			return;
		// bullet stops on static objects 
		if ((b1.isBullet() || b2.isBullet()) && bulletStaticCheck(b1,b2,contact))
			return;
			
		if (b1.isBullet() && o2 != null)
			checkForDamage(o1,o2,b1,b2);
		else if (b2.isBullet() && o1 != null)
			checkForDamage(o2,o1,b2,b1);
//		
//		if (o1 instanceof ExplosiveObject)
//			if (((ExplosiveObject) o1).blowOnContact)
//				((ExplosiveObject) o1).blow = true;
//		if (o2 instanceof ExplosiveObject)
//			if (((ExplosiveObject) o2).blowOnContact)
//				((ExplosiveObject) o2).blow = true;

	}

	private void checkForDamage(GameObject bullet, GameObject damaged,Body b1,Body b2) {
		if (((Bullet)bullet).damage == 0)
			return;
		LiveObject live;
		if (damaged instanceof StaticObject){
			createRicochetEffect(b1,b2,(Bullet) bullet);
			((Bullet) bullet).push((StaticObject) damaged);
			return;
		}
		if (!(damaged instanceof LiveObject))
			return;
		live = (LiveObject) damaged;
		Bullet b = (Bullet) bullet;
		b.lastIntersected = live;
		if (live instanceof LiveObject){
			if (Formulas.calcMissChance(b,live))
				return;
			b.doDamage(live);
		}
	}

	private boolean bulletStaticCheck(Body b1, Body b2, Contact contact) {
		if (b1.isBullet()){
			if (b2.getType() != BodyType.DynamicBody){
				if (b1.getUserData() != null)
					((Bullet)b1.getUserData()).lifeTime = 0;
				createRicochetEffect(b1,b2,((Bullet)b1.getUserData()));
				return true;
			}
		} else if (b2.isBullet()) {
			if (b1.getType() != BodyType.DynamicBody){
				if (b2.getUserData() != null)
					((Bullet)b2.getUserData()).lifeTime = 0;
				createRicochetEffect(b2,b1,((Bullet)b2.getUserData()));
				return true;
			}
		}
		return false;
	}

	void createRicochetEffect(Body b1,Body b2,Bullet b){
//		RicochetEffect eff = new RicochetEffect(b1, b2,((Bullet)b1.getUserData()));
//		RayCastRequest request = new RayCastRequest();
//		request.callback = eff;
//		request.start =  b1.getPosition();
//		request.finish =  b2.getPosition();	
//		ZombieWorld.raycasts.add(request);
//		GameState.addEffect(eff);

	}

	@Override
	public void endContact(Contact contact) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void preSolve(Contact contact, Manifold oldManifold) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void postSolve(Contact contact, ContactImpulse impulse) {
		// TODO Auto-generated method stub
		
	}

}
